package logic

import (
	"context"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"strings"

	"probe-scheduler/internal/svc"
	pb "probe-scheduler/pb/scheduler"

	"github.com/zeromicro/go-zero/core/logx"
)

type CreateTaskLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCreateTaskLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateTaskLogic {
	return &CreateTaskLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *CreateTaskLogic) CreateTask(in *pb.CreateTaskRequest) (*pb.CreateTaskResponse, error) {
	if in.Task == nil {
		return &pb.CreateTaskResponse{
			Base: &pb.CommonResponse{
				Success: false,
				Message: "task is required",
			},
		}, nil
	}
	randomStr, err := GenerateRandomString(6)
	if err != nil {
		return &pb.CreateTaskResponse{
			Base: &pb.CommonResponse{
				Success: false,
				Message: fmt.Sprintf("生成随机字符串失败: %v", err),
			},
		}, nil
	}
	uniqueName := fmt.Sprintf("%s_%s", in.Task.Name, randomStr)
	task := &pb.Task{
		Name:           uniqueName,
		Type:           in.Task.Type,
		ProbeConfig:    in.Task.ProbeConfig,
		CronExpression: in.Task.CronExpression,
		Interval:       in.Task.Interval,
		StartTime:      in.Task.StartTime,
		EndTime:        in.Task.EndTime,
	}

	// 验证任务配置
	if err := l.validateTask(task); err != nil {
		return &pb.CreateTaskResponse{
			Base: &pb.CommonResponse{
				Success: false,
				Message: err.Error(),
			},
		}, nil
	}
	// 调用DAO进行持久化
	task_ID, err := l.svcCtx.TaskDao.CreateTask(l.ctx, task)
	if err != nil {
		return &pb.CreateTaskResponse{
			Base: &pb.CommonResponse{Success: false, Message: fmt.Sprintf("创建失败: %v", err)},
		}, nil
	}

	// 调度器创建任务
	taskinfo := &pb.Task{
		Id:             task_ID,
		Name:           uniqueName,
		Type:           in.Task.Type,
		ProbeConfig:    in.Task.ProbeConfig,
		CronExpression: in.Task.CronExpression,
		Interval:       in.Task.Interval,
		StartTime:      in.Task.StartTime,
		EndTime:        in.Task.EndTime,
	}
	taskID, err := l.svcCtx.Scheduler.CreateTask(l.ctx, taskinfo)
	if err != nil {
		l.Errorf("failed to create task: %v", err)
		return &pb.CreateTaskResponse{
			Base: &pb.CommonResponse{
				Success: false,
				Message: err.Error(),
			},
		}, nil
	}

	return &pb.CreateTaskResponse{
		Base: &pb.CommonResponse{
			Success: true,
			Message: "task created successfully",
		},
		TaskId: taskID,
	}, nil
}

// 验证任务配置
func (l *CreateTaskLogic) validateTask(task *pb.Task) error {
	if task.ProbeConfig == nil {
		return fmt.Errorf("probe config is required")
	}

	if task.ProbeConfig.Target == "" {
		return fmt.Errorf("probe target is required")
	}

	switch task.Type {
	case pb.TaskType_CRON, pb.TaskType_PERIODIC:
		if task.CronExpression == "" {
			return fmt.Errorf("cron expression is required for cron/periodic tasks")
		}
	case pb.TaskType_RECURRING:
		if task.Interval <= 0 {
			return fmt.Errorf("interval must be greater than 0 for recurring tasks")
		}
	}

	return nil
}

func GenerateRandomString(length int) (string, error) {
	if length <= 0 {
		return "", fmt.Errorf("随机字符串长度必须大于0")
	}

	// 生成原始随机字节（长度为 length*3/4，base64编码后会压缩）
	rawBytes := make([]byte, length*3/4)
	_, err := rand.Read(rawBytes)
	if err != nil {
		return "", fmt.Errorf("生成随机字节失败: %w", err)
	}

	// base64编码（字母+数字+"/"+"+"），替换掉特殊字符，保留字母数字
	randomStr := base64.URLEncoding.EncodeToString(rawBytes)
	randomStr = strings.ReplaceAll(randomStr, "+", "")
	randomStr = strings.ReplaceAll(randomStr, "/", "")
	randomStr = strings.ReplaceAll(randomStr, "=", "")

	// 截取指定长度（防止编码后长度不足）
	if len(randomStr) > length {
		randomStr = randomStr[:length]
	}

	return randomStr, nil
}
